package docbookarchivemanager.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

/**
 *
 * @author Jakub Hrachovec
 */
public class ZipManager {

    private static List<String> fileList;
    private static File globalFileToBeZipped;

    /**
     * Zips given folder and outputs its content to given location.
     * @param fileToBeZipped
     * @param outputFolder
     * @param nameOfZip
     * @throws IOException
     */
    public static void zipIt(File fileToBeZipped, File outputFolder, String nameOfZip) throws IOException {
        globalFileToBeZipped = fileToBeZipped;

        fileList = new ArrayList<>();
        generateFileList(fileToBeZipped);
        byte[] buffer = new byte[1024];
        try (FileOutputStream fos = new FileOutputStream(outputFolder + File.separator + nameOfZip); ZipOutputStream zos = new ZipOutputStream(fos)) {            
            System.out.println("Creating DocBook Archive " + nameOfZip + ".");
            
            for (String zipMe : fileList) {
                
                ZipEntry ze = new ZipEntry(zipMe);
                zos.putNextEntry(ze);
                try (FileInputStream in = new FileInputStream(fileToBeZipped + File.separator + zipMe)) {
                    int len;
                    while ((len = in.read(buffer)) > 0) {
                        zos.write(buffer, 0, len);
                    }
                }
                zos.closeEntry();
            }
        }
        System.out.println("DocBook Archive " + nameOfZip + " has been created in " + outputFolder.getCanonicalPath() + ".");
    }

    /**
     * Unzips given archive and outputs its content to given location.
     * @param fileToBeUnzipped
     * @param outputFolder
     * @throws IOException
     */
    public static void unZipIt(File fileToBeUnzipped, File outputFolder) throws IOException {

        byte[] buffer = new byte[1024];
        try (ZipInputStream zis = new ZipInputStream(new FileInputStream(fileToBeUnzipped))) {
            ZipEntry ze = zis.getNextEntry();
            
            System.out.println("Unzipping DocBook Archive " + fileToBeUnzipped.getName() + ".");
            while (ze != null) {
                String fileName = ze.getName();
                File newFile = new File(outputFolder + File.separator + fileName);
                new File(newFile.getParent()).mkdirs();
                try (FileOutputStream fos = new FileOutputStream(newFile)) {
                    int len;
                    while ((len = zis.read(buffer)) > 0) {
                        fos.write(buffer, 0, len);
                    }
                }
                ze = zis.getNextEntry();
            }
            
            zis.closeEntry();
        }

    }

    private static void generateFileList(File file) throws IOException {
        if (file.isFile()) {
            fileList.add(generateZipEntry(file.getCanonicalPath()));
        }
        if (file.isDirectory()) {
            String[] subFile = file.list();
            for (String filename : subFile) {
                generateFileList(new File(file, filename));
            }
        }
    }

    private static String generateZipEntry(String file) throws IOException {
        return file.substring(globalFileToBeZipped.getCanonicalPath().length() + 1, file.length());
    }
}
